<?php

namespace app\home\controller;

// 继承的是这个路径的home控制器
use app\common\controller\Home;

// 由于上一行语句写的是继承是home控制器，这里写home
class Coupon extends Home
{
    
    //不需要登录的方法有index(),info(),receive()
    // 按理说，领取方法必须要先登录才可以领取，但是可以在下面手动判断是否有登录
    public $NoLogin = ['index', 'info', 'receive'];

    // 构造函数
    public function __construct()
    {
        // 把构造函数给到这里
        parent::__construct();

        // 加载模型，这里肯定是用到自己的模型Coupon.php和Receive.php，路径为application/common/model/Coupon
        $this->CouponModel = model('Coupon.Coupon');
        
        /* 加载模型。因为下面需要开启优惠券被领取后，数据库的两张表需要有所变化：fa_coupon优惠券的数量减少，同时fa_coupon_receive字段增加。
        因为这两个加和减的动作同时进行，而且操作同一个数据库，所以要开启事务，所以之前要先加载完这两个表的模型，上一条加载了其中一个模型，所以这里
        需要把另外一个也加载进来*/
        $this->ReceiveModel = model('Coupon.Receive');
    }

    //列表界面
    public function index()
    {

        // 查询是否有领取过优惠券，先做以下三件事
        //第一件事，判断是否有登录。
        $login = $this->IsLogin(false);
        // 第二件事，列表查询。根据数据库优惠卷列表fa_coupon的status字段,做where条件判断如果status=1,就是活动进行中,就拿这个数据,将其赋值给$list。
        // select()方法为查询多条语句
        $list = $this->CouponModel->where(['status' => '1'])->select();
        // 第三件事，当列表不为空时，
        if($list)
        {
            foreach($list as $item)
            {
                // 如果有登录信息
                if($login)
                {
                    /* 条件。表fa_coupon里面有3种优惠券，客户领取了哪种优惠券，领取记录表fa_coupon_receive这里cid就显示数字几，
                    $item['id']就是表fa_coupon的id；
                    $login['id']是登录用户的id，也就是表fa_business的id  表fa_coupon的busid，表示领取这个优惠券的用户的id*/
                    $where = ['cid' => $item['id'], 'busid' => $login['id']];
                    
                    // 根据条件去查询，如果查询的到，就表示有登录
                    $receive = $this->ReceiveModel->where($where)->find();
                    // 
                    $item['receive'] = $receive ? false : true;
                }else
                {
                    //没有登录 默认为可以领取
                    $item['receive'] = true;
                }
            }
        }

        // var_dump(collection($list)->toArray());
        // die;
        // 在这里打印可以看到，字段增加了receive[],[]里面true表示未领取，可以领取；false表示领取过，不能再领取

        // 把查询的结果$list扔会前面视图application/common/model/Coupon/coupon.html那里。在查询的结果做完if条件判断后
        $this->assign('list', $list); 

        return $this->view->fetch();
    }

    //详情界面
    public function info()
    {
        // 接收来自视图application/home/view/Coupon/index.html里面的<div class="item_content">下的：url['cid' => $item['id']]这里传过来
        $cid = $this->request->param('cid', 0, 'trim');

        //查询优惠券详细信息。
        /* 简便方法:查询条件本来应该在CouponModel后面加上一个where($cid)作为查询的条件，但是只是用id来作为查询的条件，可以把where($cid)去掉，
        把条件$cid放到后面,即find($cid)*/
        $coupon = $this->CouponModel->find($cid); 

        // 条件判断：看是否有优惠券。如果优惠券不存在，就在这里结束代码的运行
        if(!$coupon)
        {
            $this->error('优惠券不存在');
            exit;
        }

        // 以下是直接从上面列表界面那里，直接弄下来
        //第一步，判断是否有登录
        $login = $this->IsLogin(false);
        
        // 第二步，如果有登录，按照条件来查
        if($login)
        {
            // 条件
            $where = ['cid' => $cid, 'busid' => $login['id']];
            // 查询
            $receive = $this->ReceiveModel->where($where)->find();
            $coupon['receive'] = $receive ? false : true;
        }else
        {
            //没有登录 默认为可以领取
            $coupon['receive'] = true;
        }

        $this->assign('coupon', $coupon);

        return $this->view->fetch(); //给个模板
    }




    
    //领取方法。点击领取时必须先登录
    public function receive()
    {
       
        // 第一步，看是否有id过来，有就接收id；
        $cid = $this->request->param('cid', 0, 'trim');
        
        //第二步，查询优惠券详细信息。看接收的id里面是否有优惠券，有就接收；没有就提示'优惠券不存在'，同时结束程序
        $coupon = $this->CouponModel->find($cid);
        if(!$coupon)
        {
            $this->error('优惠券不存在');
            exit;
        }


        //手动判断是否登录。true表示未登录，就跳转到登录页面那里
        $this->IsLogin(true, url('home/coupon/index'));

        // 领取成功后，数据库的两个表都要有所变化

        
        //开启事务。在此之前需要在构造函数public function __construct(){}里面，加载完模型
        $this->CouponModel->startTrans();
        $this->ReceiveModel->startTrans();

        // 领取前的做的两件事，第一件事，是先查询活动是否还进行；第二件事，是查询客户是否已经领取过

        /*第一件事，判断活动是否在进行中。$coupon是先在上面做过查询的，这里是根据上面$coupon拿到
        fa_coupon表下面的字段status是1还是0，1进行，0结束*/
        if($coupon['status'] == '0')
        {
            $this->error('活动已结束');
            exit;
        }

        //第二件事，查询当前用户是否有领取过该优惠券。设置where条件，判断这两个id是否都相等，都相等就符合条件

        /* 注意：防止搞混。这里要不都设置为cid，不要一些id一些又cid，最好把这三个地方id都保持一样，均改为cid，第一个地方：
        在这个控制器，上面领取方法那里；第二个地方：路径为application/home/view/coupon/index.html里面的<a herf=>里面；第三个地方，
        详情页面的info(),路径为application/home/view/coupon/info.html*/
        $where = [
            'cid' => $cid,
            'busid' => $this->view->AutoLogin['id']
        ];

        $check = $this->ReceiveModel->where($where)->find();

        if($check)
        {
            $this->error('已领取过该优惠券，不能重复领取');
            exit;
        }

        // 获取总数total
        // 第一步，先判断，有就获取
        // 第二步，将获得的总数total转化为正整数
        // 第三步，不能让总数total小于0。如果小于0，就让其为0
        // 第四步，让total做一个自减
        $total = isset($coupon['total']) ? trim($coupon['total']) : 0;
        $total = intval($total);
        $total = $total < 0 ? 0 : $total;
        $total--;



        //领取成功后，需要做两件事情：第一件事，优惠券(更新表)；第二件事，优惠券领取表(插入)

        //第一件事，优惠券表的更新
        // 注意：执行更行语句中必须要有id，因为有id，save()方法可以识别到id
        // 插入数组
        $CouponData = [
            'id' => $cid,
            'total' => $total
        ];


        // 把数组更新到模型，$this->CouponModel这个表示；最后插入到数据库，save($CouponData)这个表示
        $CouponStatus = $this->CouponModel->isUpdate(true)->save($CouponData);

        //  var_dump($CouponStatus);
        // exit;
       

        // 判断是否成功更新了优惠券的数量，若失败，就提醒，同时结束。这里无需做回滚，因为这里是第一个操作，前面已经没有操作了
        if($CouponStatus === FALSE)
        {
            $this->error('更新优惠券数量失败');
            exit;
        }

        // 更新成功后，做第二件事情

        //第二件事，优惠券领取表的插入。三步：第一步，组装数组，第二步，把组装好的数组更新到模型，第三步，判断是否插入成功
        //第一步，组装数组
        $ReceiveData = [
            'cid' => $cid,
            'busid' => $this->view->AutoLogin['id'],
            'status' => '1'
        ];

        // 第二步，把组装好的数组更新到模型，这里就不加isUpdate，因为不是更新。
        // 验证器validate()在fast/application/common/validate/Coupon/Receive.php
        // $ReceiveData[]组装好数据，就在这一步插入
        $ReceiveStatus = $this->ReceiveModel->validate('common/Coupon/Receive')->save($ReceiveData);

        // 第三步，判断是否插入成功。
        if($ReceiveStatus === FALSE)
        {
            // 不成功就他的上一步做回滚
            $this->CouponModel->rollback();
            /* 如果发生错误，需要回滚。就会提示因为什么发生错误的信息，获取信息的位置，在验证器为fast/application/common/validate/Coupon/Receive.php里，
            在那边Receive.php里的第二步$message这里，就是把错误信息给过来*/
            $this->error($this->ReceiveModel->getError());
            exit;
        }

        //综合判断
        // 回滚和提交的顺序不一样：回滚是，从后面往前进行<-；提交是，从前面往后面进行->
        if($CouponStatus === FALSE || $ReceiveStatus === FALSE)
        {
            $this->ReceiveModel->rollback();
            $this->CouponModel->rollback();
            $this->error('领取失败');
            exit;
        }else
        {
            //提交事务
            $this->CouponModel->commit();
            $this->ReceiveModel->commit();
            $this->success('领取成功', url('home/coupon/index'));
            exit;
        }
    }
}
